#ifndef TESTSTREAM_H_
#define TESTSTREAM_H_

#include "DataStream.h"
#include <queue>

namespace uav
{
namespace comm
{

/**
 * @class TestStream
 *
 * @brief Data stream classing using a string source for testing purposes.
 *
 * @author Travis Portz
 */
class TestStream : public DataStream
{
public:
	explicit TestStream(const std::string &str);

	/**
	 * Adds the provided string to the data stream's input.
	 */
	void addInput(const std::string &str);

	/**
	 * Removes any data buffered for the stream's input.
	 */
	void clearInput();

	bool isDataAvailable() const;

	/**
	 * Reads a single byte.
	 */
	uint8_t readByte();

	/**
	 * Reads the specified number of bytes into @a buffer.
	 */
	void read(std::vector<uint8_t> &buffer, int numBytes);

	/**
	 * Reads a line of characters up to @e and @e including
	 * the specified terminator.
	 */
	std::string readLine(char terminator = '\n');

	/**
	 * Write a single byte
	 */
	bool writeByte(uint8_t dataByte);

	/**
	 * Writes the data from the provided vector.
	 */
	bool write(const std::vector<uint8_t> &buffer);

	/**
	 * Writes a string.
	 */
	bool write(const std::string &str);

	/**
	 * Gets the stored output from all of the write operations.
	 */
	const std::vector<uint8_t>& getOutput() const;

	/**
	 * Clears the stored output of all the write operations.
	 */
	void clearOutput();

private:
	std::queue<uint8_t> input;
	std::vector<uint8_t> output;
};

inline bool TestStream::isDataAvailable() const { return !input.empty(); }
inline const std::vector<uint8_t>& TestStream::getOutput() const { return output; }
inline void TestStream::clearOutput() { output.clear(); }
inline void TestStream::clearInput() { while (!input.empty()) input.pop(); }

}

}

#endif
